<?php

namespace App\Http\Controllers\v1\designPattern\concurrency;

use App\Http\Controllers\Controller;
use phpDocumentor\Reflection\Types\True_;

/**
 * 并发模式之线程池模式
 * 线程池
 * 基于Thread and Threaded 类实现
 */

class ThreadPool extends Controller
{
    /**
     * 最大线程个数
     * @var $maxThread
     */
    private $maxThread;

    /**
     * 线程池已有线程
     * @var array $threads
     */
    private $threads = [];

    /**
     * 投递任务的队列
     * @var array $queue
     */
    private $queue = [];

    public function __construct(int $maxThread)
    {
        parent::__construct();
        $this->maxThread = $maxThread;
    }

    /**
     * 向queue队列投递任务并开启线程
     * @param $task
     * @return void
     */
    public function addTask($task)
    {
        $this->queue[] = $task;
        $this->startThread();
    }

    /**
     * 当已有线程池的线程数量小于最大线程数
     * 时，向线程池中加入线程
     * @return void
     */
    private function startThread()
    {
        if (count($this->threads) < $this->maxThread) {
            $thread = new Thread($this);
            $this->threads[] = $thread;
            $thread->start();
        }
    }

    /**
     * 在队列中获取一个任务
     * @return mixed|null
     */
    public function getTask()
    {
        return array_shift($this->queue);
    }

    /**
     * 队列中是否有任务
     * @return bool
     */
    public function hasTask(): bool
    {
        return !empty($this->queue);
    }

    /**
     * 删除指定线程
     * @param Thread $thread
     * @return void
     */
    public function removeThread(Thread $thread)
    {
        foreach ($this->threads as $key => $t) {
            if ($t === $thread) {
                unset($this->threads[$key]);
                break;
            }
        }
    }


}